﻿using System;
using System.Collections.Generic;
using System.Text;
using SH;

namespace MTS
{

    class mtVHostManager
    {
        bool m_bInit = false;
        bool m_bActive = false;
        readonly object m_mtx = new object();

        MTSDLLWrap _mts;
        Dictionary<emProgramType, mtVHost> m_mapVHost = new Dictionary<emProgramType, mtVHost>();

        //  degtOnCallbackOneWay m_pfnCallbackOneWay;
        //   degtOnCallbackTwoWay m_pfnCallbackTwoWay;
        // degtOnStationInfoNotify m_pfnStationInfoNotify;

        public shErrorCode Initialize()
        {
            _mts = MTSDLLWrap.getInstance();

            shLog.TraceInfo("Initialize .Net MessTransceiver.");

            return shErrorCode.sh_ec_Success;
        }

        public shErrorCode Start()
        {
            lock (m_mtx)
            {
                if (m_bInit == false)
                    return shErrorCode.sh_ec_WaitingForInit;

                if (m_bActive == true)
                    return shErrorCode.sh_ec_Success;

                foreach (var m in m_mapVHost)
                {
                    m.Value.Start();
                }

                m_bActive = true;
            }

            return shErrorCode.sh_ec_Success;
        }

        public shErrorCode Stop()
        {
            lock (m_mtx)
            {
                if (m_bInit == false)
                    return shErrorCode.sh_ec_WaitingForInit;

                if (m_bActive == false)
                    return shErrorCode.sh_ec_Success;

                foreach (var m in m_mapVHost)
                {
                    m.Value.Stop();
                }
                m_bActive = false;
            }

            return shErrorCode.sh_ec_Success;
        }


        public shErrorCode DestroyVHost(mtVHost host)
        {
            lock (m_mtx)
            {
                if (m_mapVHost.ContainsKey(host.ProgramType))
                {
                   if(0 == host.DecCount())
                    {
                        m_mapVHost.Remove(host.ProgramType);

                        _mts.mtCRelease(host.Handle);
                    }
                }
            }

            return shErrorCode.sh_ec_Success;
        }

        mtVHost MakeHost(mtRegisterInfo info)
        {
            if(m_bInit == false)
            {
                _mts.mtInitialize();

                m_bInit = true; 
            }

            mtCRegisterInfo cInfo = new mtCRegisterInfo
            {
                bAutoConnect = (byte)(info.IsAutoConnect ? 1 : 0),
                bAutoLogon = (byte)(info.IsAutoLogon ? 1 : 0),
                location = info.Location,
                nConnectInterval = info.ConnectInterval,
                nHeartInterval = info.HeartInterval,
                stationType = (int)info.StationType,
                stationName = info.StationName,
                programType = (int)info.ProgramType,
                userName = info.UserName,
                password = info.Password,
                nMaxHeartFailCount = info.MaxHeartFailCount,
                nLanguageID = info.LanguageID
            };

            var handle = _mts.mtCGet(ref cInfo);

            if (handle != 0)
            {
                mtVHost host = new mtVHost(handle, info, true);

                return host;
            }
            else
                return null;

        }

        public mtVHost CreateVHost( mtRegisterInfo info)
        {
            mtVHost host;

            lock(m_mtx)
            {
                if (m_mapVHost.TryGetValue(info.ProgramType, out host) == false)
                {
                    host = MakeHost(info);

                    if (host != null)
                    {
                        var hRet = host.Initialize();

                        if (hRet == shErrorCode.sh_ec_Success)
                        {
                            host.IncCount();
                            m_mapVHost.Add(info.ProgramType, host);
                        }
                    }
                }
                else
                {
                    host.IncCount();

                }
            }

            return host;
        }
    }
}
